import java.util.PriorityQueue;

//模拟实现定时器
public class MyTimer {
    private Thread t = null;//负责扫描队列，执行任务的线程
    private PriorityQueue<MyTimerTask> queue = new PriorityQueue<>();//任务队列

    private Object locker = new Object();

    public void schedule (Runnable runnable,long delay){
        synchronized (locker) {
            MyTimerTask task = new MyTimerTask(runnable, delay);
            queue.offer(task);
            //添加新的元素之后 就可以通知唤醒了
            locker.notify();
        }
    }

    //构造方法
    //创建扫描线程 让扫描线程来完成判定和执行
    public MyTimer(){
        t = new Thread(()->{
            //扫描线程需要循环扫描队首元素，检查队首元素是否到执行时间了
            //到了 执行任务 并且把任务从队列中删除
            while (true) {
                try {
                    //while 内加锁 可能会重复快速加锁 schedule无法加锁 线程饿死—— wait
                    synchronized (locker) {//锁加到while里面 才有释放锁的机会
                        //使用while多一步判断
                        while(queue.isEmpty()) {
                            //队列为空 不能继续执行了 应该先wait
                            locker.wait();
                        }
                        MyTimerTask task = queue.peek();
                        //获取当前时间并和队首元素的时间比较
                        long curTime = System.currentTimeMillis();
                        if (curTime >= task.getTime()) {
                            //时间到了 执行任务
                            queue.poll();
                            task.run();
                        } else {
                            //没到时间 暂时先不做处理
                            //避免“忙等”——在wait但是cpu很忙
                            //需要先把锁让出来 所以不能使用sleep 避免错过新的任务
                            locker.wait(task.getTime()-curTime);
                        }
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
    }

    public void cancel(){
        //结束t线程

    }
}
